var insertedRows = new Array();
var removedRows = new Array();
var updatedRows = new Array();
var insertCounter = 0;
var updateCounter = 0;

$(document).ready(function() {
    $("#observation_observationdate").datepicker({dateFormat: 'yy-mm-dd'});
    $("#observation_lat").numeric();
    $("#observation_lng").numeric();
    $( "#observation-form-dialog").dialog( "destroy" );

    var researchId = getParamValue(window.location.href, "id");
        locationName = $("#observation_location"),
        lat = $("#observation_lat"),
        lng = $("#observation_lng"),
        remarks = $("#observation_remarks");
        observationDate = $("#observation_observationdate");
        allFields = $([]).add(locationName).add(lat).add(lng).add(remarks).add(observationDate);

    // show new observation form dialog
    $("#observation-form-dialog").dialog({
        autoOpen: false,
        closeOnEscape: true,
        modal: false,
        position: 'center',
        show: 'blind',
        hide: 'blind',
        width: '400px',
        close: function() {
            allFields.val( "" ).removeClass( "ui-state-error" );
            $("#validate-tip").text("");
            $('#validate-tip').removeClass("ui-state-error");
        }
    });

    //  handler for adding new row
    $("#new-obs").button().click(function() {

        allFields.val( "" ).removeClass( "ui-state-error" );

        // set buttons: add, close
        $("#observation-form-dialog").dialog('option', 'buttons', {
            "add observation" : function() {
                allFields.removeClass( "ui-state-error" );
                var success = saveObservation('add', new Array(locationName.val(), lat.val(), lng.val(), remarks.val(), observationDate.val()));
                if (success) {
                    allFields.val( "" ).removeClass( "ui-state-error" );
                    $("#validate-tip").text("");
                    $('#validate-tip').removeClass("ui-state-error");
                }
            },
            "close" : function(){
                $(this).dialog("close");
            }
        });

        $("#observation-form-dialog").dialog('open');
    });

    // back button
    $("#back-dir").button({icons: {primary: 'ui-icon-circle-arrow-w'}});

    // save-changes button
    $("#save-obs").button().click(function(){
        saveChanges(researchId);
    });

});

function validate() {
    if (locationName.val() == "") {
        $('#validate-tip').text("Location name must not be empty");
        $('#validate-tip').addClass("ui-state-error");
        locationName.addClass("ui-state-error");
        return false;
    }

    if (lat.val() == "") {
        $('#validate-tip').text("Latitude name must not be empty");
        $('#validate-tip').addClass("ui-state-error");
        lat.addClass("ui-state-error");
        return false;
    }

    if (lat.val() > 90 || lat.val() < -90) {
        $('#validate-tip').text("Latitude value is out of range (-90 to 90)");
        $('#validate-tip').addClass("ui-state-error");
        lat.addClass("ui-state-error");
        return false;
    }

    if (lng.val() == "") {
        $('#validate-tip').text("Longitude name must not be empty");
        $('#validate-tip').addClass("ui-state-error");
        lng.addClass("ui-state-error");
        return false;
    }

    if (lng.val() > 180 || lng.val() < -180) {
        $('#validate-tip').text("Longitude value is out of range (-180 to 180)");
        $('#validate-tip').addClass("ui-state-error");
        lng.addClass("ui-state-error");
        return false;
    }


    return true;
}

/*
 * add new line into observation list (table),
 * add into new records collection
 **/
function saveObservation(method, fields) {

    if (!validate()) return false;

    // observation object
    var obj = new Object;
    obj.location = fields[0];
    obj.lat = fields[1];
    obj.lng = fields[2];
    obj.remarks = fields[3];
    obj.observationdate = fields[4];

    if (method == 'add') {

        // only add method has dirtyid
        obj.dirtyid = insertCounter;

        // add new record to array
        // insertedRows[insertCounter] = obj;
        insertedRows.push(obj);

        // add its html into table
        $("#observation-table tbody").append(constructLine(obj));

        // set click handler to cancel added row
        $("#cancel_"+(insertCounter))
        .button({
            icons: {primary: 'ui-icon-close'},
            text: true
        })
        .click(function(){
            var dirtyid = $(this).attr("id").replace("cancel_", "");
            for(i=0; i<insertedRows.length; i++) {
                if (insertedRows[i].dirtyid == dirtyid) {
                    insertedRows.splice(i, 1);
                    break
                }
            }
            $("#dirty_"+dirtyid).remove();
        });

        insertCounter++;

    } else if (method == 'edit') {

        // only edit method has observation id
        obj.id = fields[5]

        // add updated rows
        var found = 0;
        for(i = 0; i < updatedRows.length; i++ ) {
            if (updatedRows[i].id == obj.id) {
                updatedRows[i] = obj;
                found = 1;
                break;
            }
        }
        if (!found) {
            updatedRows.push(obj);
        }

        // update table values
        $("#observation_" + obj.id + "_location").html(locationName.val());
        $("#observation_" + obj.id + "_lat").html(lat.val());
        $("#observation_" + obj.id + "_lng").html(lng.val());
        $("#observation_" + obj.id + "_remarks").html(remarks.val());
        $("#observation_" + obj.id + "_date").html(observationDate.val());

        //update row color to mark as changed
        $("#observation_" + obj.id + "_location")
        .add($("#observation_" + obj.id + "_lat"))
        .add($("#observation_" + obj.id + "_lng"))
        .add($("#observation_" + obj.id + "_remarks"))
        .add($("#observation_" + obj.id + "_date"))
//            .css({'font-style': 'italic', 'color' : 'red'});
        .addClass('ui-state-error-text');
    }

    return true;
}

/*
* create new html row of table
**/
function constructLine(obj) {
    return "<tr id='dirty_"+ obj.dirtyid +"'>" +
            "<td style='font-size: 75%;' align='left'>"+
                    "<button id='cancel_"+ obj.dirtyid +"' title='Cancel'>Cancel</button>" +
                "</td>" +
            "<td class='ui-state-error-text'>"+ obj.location +"</td>" +
            "<td class='ui-state-error-text'>"+ obj.lat +"</td>" +
            "<td class='ui-state-error-text'>"+ obj.lng +"</td>" +
            "<td class='ui-state-error-text'>"+ obj.remarks +"</td>" +
            "<td class='ui-state-error-text'>"+ obj.observationdate +"</td>" +
            "</tr>";
}

function edit(element) {

    // observation id
    var id = element.attr('id').replace('edit', '');

    // set buttons: add, close
    $("#observation-form-dialog").dialog('option', 'buttons', {
        "Edit" : function() {
            allFields.removeClass( "ui-state-error" );
            var success = saveObservation('edit', new Array(locationName.val(), lat.val(), lng.val(), remarks.val(), observationDate.val(), id));
            if (success) {
                allFields.val( "" ).removeClass( "ui-state-error" );
                $("#validate-tip").text("");
                $('#validate-tip').removeClass("ui-state-error");
                $(this).dialog("close");
            }
        },
        "close" : function(){
            $(this).dialog("close");
        }
    });

    $("#observation-form-dialog").dialog('open');

    var loc = $("#observation_" + id + "_location a");
    if (loc.text() == "") {
        locationName.val($("#observation_" + id + "_location").html());
    }
    else {
        locationName.val(loc.text());
    }
    lat.val($("#observation_" + id + "_lat").html());
    lng.val($("#observation_" + id + "_lng").html());
    remarks.val($("#observation_" + id + "_remarks").html());
    observationDate.val($("#observation_" + id + "_date").html());
}

function remove(element){
    var id = element.attr("id").replace('remove', '');

    $("#edit"+id).button("disable");

    // if remove clicked, add the id into array. otherwise, remove from array
    if (element.button('option', 'label') == "Remove") {
        element.button('option', 'label', "Undo");
        element.button('option', 'icons', { primary: 'ui-icon-arrowreturnthick-1-w' } );
        element.attr('title', 'Undo remove');

        removedRows.push(id);

        // set row color to gray
        $('td[id*="observation_'+id+'"]').each(function(){
            $(this).css('color', '#BBBBBB');
            $(this).children().each(function(){
                $(this).css('color', '#BBBBBB');
            });
        })
    } else {
        element.button('option', 'label', "Remove");
        element.button('option', 'icons', { primary: 'ui-icon-trash' } );
        element.attr('title', 'Remove');

        for(i=0; i<removedRows.length; i++) {
            if (removedRows[i] == id) {
                removedRows.splice(i, 1);
                break;
            }
        }
        $("#edit"+id).button("enable");

        // reset row color
        $('td[id*="observation_'+id+'"]').each(function(){
            $(this).css('color', '');
            $(this).children().each(function(){
                $(this).css('color', '');
            });
        })
    }
}

/*
 * save new records, delete records
 **/
function saveChanges(researchId) {
//        alert(JSON.stringify(insertedRows));

    if (insertedRows.length == 0 && removedRows.length == 0 && updatedRows.length == 0) {
        alert("No changes.");
        return false;
    }
    $.ajax({
        type: "POST",
        url: $("#save-obs").attr("link"),
        data: {inserts: JSON.stringify(insertedRows), removes: JSON.stringify(removedRows), updates: JSON.stringify(updatedRows)},
        dataType: "html",
        success: function(data, textStatus, jqXHR) {
            $("#table-wrap").html(data);
            return true;
        },
        error: function(jqXHR, textStatus, errorThrown) {
            alert("error: " + textStatus + ", " + errorThrown);
            return false;
        }
    });

    // clear rows
    insertedRows = new Array();
    removedRows = new Array();
    updatedRows = new Array();
    insertCounter = 0;
    
    return true;
}